package org.jflame.context.spring;

import org.jflame.commons.config.ConfigHolder;

import java.util.Locale;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.i18n.LocaleContextHolder;

/**
 * Spring ApplicationContext holder
 * 
 * @author zyc
 */
public final class SpringContextHolder implements ApplicationContextAware {

    private static ApplicationContext springContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextHolder.springContext = applicationContext;
    }

    /**
     * 返回spring上下文环境对象
     * 
     * @return ApplicationContext
     */
    public static ApplicationContext getSpringContext() {
        return springContext;
    }

    /**
     * 按名称获取spring bean
     * 
     * @param name
     * @return
     */
    public static Object getBean(String name) {
        return springContext.getBean(name);
    }

    /**
     * 按类型获取spring bean
     * 
     * @param requiredType
     * @return
     */
    public static <T> T getBean(Class<T> requiredType) {
        return springContext.getBean(requiredType);
    }

    public static String getMessage(String code) {
        return springContext.getMessage(code, null, LocaleContextHolder.getLocale());
    }

    /**
     * 返回多语言资源文件中的文本信息,使用系统默认区域
     * 
     * @param code key
     * @param args 变量参数
     * @return
     */
    public static String getMessage(String code, Object... args) {
        return springContext.getMessage(code, args, LocaleContextHolder.getLocale());
    }

    public static String getMessage(String code, String... args) {
        return springContext.getMessage(code, args, LocaleContextHolder.getLocale());
    }

    /**
     * 返回多语言资源文件中的文本信息,使用系统默认区域
     * 
     * @param code key
     * @param args 变量参数
     * @param defaultMessage 缺省文本
     * @return
     */
    public static String getMessage(String code, Object[] args, String defaultMessage) {
        return springContext.getMessage(code, args, defaultMessage, LocaleContextHolder.getLocale());
    }

    /**
     * 返回多语言资源文件中的文本信息
     * 
     * @param code key
     * @param args 变量参数
     * @param defaultMessage 缺省文本
     * @param locale 区域
     * @return
     */
    public static String getMessage(String code, Object[] args, String defaultMessage, Locale locale) {
        return springContext.getMessage(code, args, defaultMessage, locale);
    }

    public static String getMessage(String code, String defaultMessage, Locale locale) {
        return springContext.getMessage(code, null, defaultMessage, locale);
    }

    /**
     * 发布事件到spring
     * 
     * @param event
     */
    public static void pushEvent(ApplicationEvent event) {
        springContext.publishEvent(event);
    }

    /**
     * 动态注册bean, 类名首字母小写作为beanName
     * 
     * @param beanClass
     */
    public static void registerBean(Class<?> beanClass) {
        registerBean(org.springframework.util.StringUtils.uncapitalize(beanClass.getSimpleName()), beanClass);
    }

    /**
     * 动态注册Bean
     *
     * @param beanName bean名称
     * @param beanClass bean对应的类
     */
    public static void registerBean(String beanName, Class<?> beanClass) {
        // 获取BeanFactory
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) springContext
                .getAutowireCapableBeanFactory();
        // 创建bean信息.
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(beanClass);
        // 动态注册bean.
        defaultListableBeanFactory.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
    }

    /**
     * 动态卸载Bean
     *
     * @param beanName bean名称
     */
    public static void unregisterBean(String beanName) {
        // 获取BeanFactory
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) springContext
                .getAutowireCapableBeanFactory();
        defaultListableBeanFactory.removeBeanDefinition(beanName);
    }

    public static String getProperty(String key) {
        return springContext.getEnvironment()
                .getProperty(key);
    }

    public static String getProperty(String key, String defaultValue) {
        return springContext.getEnvironment()
                .getProperty(key, defaultValue);
    }

    /**
     * 将spring配置环境对象注入到ConfigHolder中, 使得可以使用ConfigHolder获取spring配置属性
     */
    public static void holdEnv() {
        ConfigHolder.setConfig(new SpringPropertiesConfig(springContext.getEnvironment()));
    }

}
